import sys
import logging
import argparse

from json import loads as json_loads
import time
from urllib import parse, request
from urllib.request import urlopen

from config import read_cfg


logger = logging.getLogger("RuiJie-ePort")


class App(object):
    def __init__(self):
        parser = argparse.ArgumentParser(description="RuiJie-ePort Cli Tool")
        g1 = parser.add_mutually_exclusive_group()
        g2 = parser.add_mutually_exclusive_group()
        g3 = parser.add_mutually_exclusive_group()
        parser.add_argument(
            "-f", "--file", type=str, default="config.yml", help="use config file"
        )
        g1.add_argument(
            "-C",
            "--connect",
            action="store_true",
            help="use config file ,connect to the net ",
        )
        g2.add_argument("-T", "--test", action="store_true", help="test net")
        g3.add_argument("-D", "--disconnect", action="store_true", help="disconnect")
        self.args = args = parser.parse_args()

        self.cfg = cfg = read_cfg(args.file)
        self.headers = cfg["headers"] | {
            "Connection": "keep-alive",
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.51 Safari/537.36 Edg/99.0.1150.39",
            "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
            "Accept": "*/*",
            "Accept-Encoding": "gzip, deflate",
            "Accept-Language": "zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7",
            "Cookie": parse.quote(cfg["cookie"]),
            "Host": cfg["url"]["server"].replace("http://", "").replace("https://", ""),
            "Origin": cfg["url"]["server"],
        }

        self.login_data = cfg["login_data"]
        self.logout_data = cfg["logout_data"]

    def run(self):
        if self.args.connect:
            if self.cfg["funtion"]["check_school_network"] and not self.test_internet(
                host=self.cfg["url"]["server"], timeout=3
            ):
                logger.warning(
                    msg="非校园网环境\n当前不在校园网环境，10s后重新检测\n若您的系统刚启动，可能还没反应过来，没有连上任何网络，为正常现象",
                )
                time.sleep(10)
            if not self.test_internet(host=self.cfg["url"]["server"], timeout=2):
                logger.warning(
                    msg="非校园网环境\n当前不在校园网环境，不自动尝试联网，程序自动退出",
                )
                sys.exit(0)
            if self.test_internet():
                if self.cfg["funtion"]["disconnect_network"]:
                    logger.info(msg="设备已联网\n网络本来就是通的噢~")
                    sys.exit(0)
        elif self.args.test:
            print(self.test_internet())
        elif self.args.disconnect:
            self.disconnect()
        else:
            logger.info("请使用-h查看帮助")

    def test_internet(
        self,
        host: str = "http://edge-http.microsoft.com/captiveportal/generate_204",
        timeout: int = 1,
    ) -> bool:
        ###    测试网络通断状态
        ###    Args:
        ###        host(str): 用于测试连接状态的generate_204服务器地址
        ###        timeout(int): 超时时间（单位：秒）
        ###    Returns:
        ###        bool: True表示连接正常，False表示连接异常

        try:
            resp = urlopen(host, timeout=timeout)
            if host.endswith("generate_204"):
                return resp.status == 204
            elif 200 <= resp.status <= 208 or resp.status == 226:
                return True
            return False
        except:  # noqa
            return False

    def disconnect(self):

        resp = request.Request(
            self.cfg["url"]["server"] + self.cfg["url"]["logout"],
            data=bytes(parse.urlencode(self.login_data).encode("utf-8")),
            headers=self.headers,
            origin_req_host=None,
            unverifiable=False,
            method="POST",
        )

        try:
            res = request.urlopen(resp, timeout=10)
        except Exception as e:
            error_message = f"出现错误:\n{str(e)}"
            logger.error(error_message)
            sys.exit(1)
        else:
            status = json_loads(res.read().decode())
            if status["result"] == "success":
                logger.info(msg="断网成功！")
            elif status["result"] == "fail":
                logger.error(f'断网失败:\n{status["message"]}')
            else:
                logger.error(f"未知错误：{status}")

    def connect(self):

        resp = request.Request(
            self.cfg["url"]["server"] + self.cfg["url"]["login"],
            data=(
                bytes(parse.urlencode(self.login_data).encode("utf-8"))
                if self.login_data
                else None
            ),
            headers=self.headers,
            origin_req_host=None,
            unverifiable=False,
            method="POST",
        )

        try:
            res = request.urlopen(resp, timeout=10)
        except Exception as e:
            logger.error(f"出现错误:\n{str(e)}")
            sys.exit(1)
        else:
            status = json_loads(res.read().decode())
            if status["result"] == "success" and status["message"] == "":
                logger.info("网络已连接！")
            elif status["result"] == "success":
                logger.info(status["message"])
            elif status["result"] == "fail":
                logger.error(f'未知错误:\n{status["message"]}')
            else:
                logger.error(f"未知错误:\n{status}")


def main():
    app = App()
    app.run()


if __name__ == "__main__":
    main()
